<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">











<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>ioko-tapestry-commons - </title>
    <style type="text/css" media="all">
      @import url("./css/maven-base.css");
      @import url("./css/maven-theme.css");
      @import url("./css/site.css");
    </style>
    <link rel="stylesheet" href="./css/print.css" type="text/css" media="print" />
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
                                                    
<script src="http://www.google-analytics.com/ga.js" type="text/javascript"></script>
                                                        
<script src="http://www.google-analytics.com/ga.js" type="text/javascript">try {
                var pageTracker = _gat._getTracker("UA-75598-9");
                pageTracker._trackPageview();
                } catch(err) {}</script>
                    </head>
  <body class="composite">
    <div id="banner">
                  <a href="http://tapestry.formos.com/projects/ioko-tapestry-commons/" id="bannerLeft">
    
                                            <img src="images/tapestry-commons.png" alt="" />
    
            </a>
                        <a href="http://www.ioko.com/" id="bannerRight">
    
                                            <img src="images/ioko.png" alt="" />
    
            </a>
            <div class="clear">
        <hr/>
      </div>
    </div>
    <div id="breadcrumbs">
          
  

  
    
            
  
    
            <div class="xleft">
        Last Published: 2009-09-24
                      </div>
            <div class="xright">      
  

  
    
            
  
    
             Version: 1.6.0-SNAPSHOT
      </div>
      <div class="clear">
        <hr/>
      </div>
    </div>
    <div id="leftColumn">
      <div id="navcolumn">
           
  

  
    
            
  
    
                             <h5>Sites</h5>
            <ul>
              
    <li class="none">
                    <a href="http://tapestry.formos.com/projects/ioko-tapestry-commons/" class="externalLink">Release Site</a>
          </li>
              
    <li class="none">
                    <a href="http://tapestry.formos.com/nightly/ioko-tapestry-commons/" class="externalLink">Nightly Site</a>
          </li>
          </ul>
              <h5>How To</h5>
            <ul>
              
    <li class="none">
                    <a href="./ajax.html">AJAX into a Flash movie</a>
          </li>
          </ul>
              <h5>Project Documentation</h5>
            <ul>
              
                
              
      
            
      
            
      
            
      
            
      
            
      
            
      
            
      
            
      
            
      
            
      
            
      
              
        <li class="collapsed">
                    <a href="project-info.html">Project Information</a>
                </li>
              
                
              
      
              
        <li class="collapsed">
                    <a href="project-reports.html">Project Reports</a>
                </li>
          </ul>
                                                     <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy">
            <img alt="Built by Maven" src="./images/logos/maven-feather.png"></img>
          </a>
                       
  

  
    
            
  
    
        </div>
    </div>
    <div id="bodyColumn">
      <div id="contentBox">
        <div class="section"><h2>How to get Flash (or Flex) talking AJAX to Tapestry Pages</h2>
<p>If you want your flash component to talk to an event handler in your tapestry page and then process the response. The sequence will be</p>
<ul><li>Tapestry renders page with swfobject on</li>
<li>SwfObject has event URL's passed into it via flashvars</li>
<li>Flex calls those url's directly using it http client</li>
<li>Tapestry fires the event and the event returns a JSON block</li>
<li>Flex parses the JSON block using ASCorelib <a class="externalLink" href="http://code.google.com/p/as3corelib/">http://code.google.com/p/as3corelib/</a></li>
</ul>
<div class="section"><h3>A worked example</h3>
<p>This worked example is part of the unit tests for this library. To see this working checkout the code and in this project type</p>
<div class="source"><pre>   mvn jetty:run</pre>
</div>
<p>Jetty will start and on <a class="externalLink" href="http://localhost:8080/SwfObjectAjaxPage">http://localhost:8080/SwfObjectAjaxPage</a> you will see the working example.</p>
<div class="section"><h4>The Tapestry Page</h4>
<p>On your page class you need to * add the flash movie</p>
<ul><li>pass into to it via flashvars the event url</li>
<li>create an event handler to handle the event and then return a JSON response<div class="source"><pre>public class SwfObjectAjaxPage {

        @Property
        private JSONObject flashvars;

        @Inject
        private ComponentResources componentResources;

        @Environmental
        private RenderSupport renderSupport;

        public void setupRender() {
                flashvars = new JSONObject();
                flashvars.append(&quot;ajaxRequestUrl&quot;, componentResources.createEventLink(&quot;ajaxRequest&quot;).toAbsoluteURI() );

        }

        /**
         * Called on the AJAX Request
         *
         * Note we could return the json object directly if we got flash to set the XMLHTTPRequest headers.
         * @return
         */
        public Object onAjaxRequest(){
                JSONObject myResults = new JSONObject();
                myResults.append(&quot;Cat&quot;, &quot;Parsnip&quot;);
                return new TextStreamResponse(&quot;application/json&quot;, myResults.toString());
        }
}
</pre>
</div>
<div class="source"><pre>&lt;html xmlns:t=&quot;http://tapestry.apache.org/schema/tapestry_5_1_0.xsd&quot;&gt;
&lt;head&gt;&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;Swf Object Test Page&lt;/h1&gt;
&lt;div t:id=&quot;swfObject&quot; t:type=&quot;ioko/swfObject&quot; width=&quot;300&quot; height=&quot;300&quot; swf=&quot;asset:FlexAjax.swf&quot;
     flashvars=&quot;flashVars&quot;&gt;
    &lt;p&gt;Non Flash Content&lt;/p&gt;
&lt;/div&gt;
&lt;/body&gt;
</pre>
</div>
</li>
</ul>
</div>
<div class="section"><h4>The Flex (or Flash) movie</h4>
<p>In the movie you need to * Get the url from the flash vars</p>
<div class="source"><pre>    private function setupAjax():void{
                                ajaxHelper = new AjaxHelper(Application.application.parameters.ajaxRequestUrl, processResult);
                                ajaxHelper.ExecuteAjax();
                        }</pre>
</div>
<ul><li>Work out the correct absolute URL (I have done this in a 'helper class'). I have used the External Interface you could also use the Browser interface but that requires a lot of Adobe Javascript to be loaded.</li>
<li>Make a request to the URL</li>
<li>Parse the response via the JSON library from ASCorelib <a class="externalLink" href="http://code.google.com/p/as3corelib/">http://code.google.com/p/as3corelib/</a> . In the example I simply copied all the files required for JSON into my source path. Alternatively you can add a dependency on the library via flash/flex.<div class="source"><pre>public class AjaxHelper
        {
                private var url:URLRequest
                private var dataReciever:Function;
                public var lastData:Object;

                public function AjaxHelper(passedUrl:String, dataReciever:Function)
                {
                        // Passed URL is relative to current site so we need to add the domain name etc on the front
                        var pageUrl:String = ExternalInterface.call(&quot;window.location.href.toString&quot;);
                        var fixedUrl:String = URLUtil.getProtocol(pageUrl) + &quot;://&quot; + URLUtil.getServerNameWithPort(pageUrl) + passedUrl;

                        url = new URLRequest(fixedUrl);
                        this.dataReciever = dataReciever;               }

                public function ExecuteAjax():void{
                        var loader:URLLoader = new URLLoader;
                        loader.addEventListener(Event.COMPLETE, function(e:Event):void {
                           lastData = JSON.decode(loader.data);
                           dataReciever(lastData);
                    })
                        loader.load(url);
                }

        }</pre>
</div>
</li>
<li>When this exectues it calls back with the data AND it puts it in a public property called lastData</li>
<li>You can then read the JSON data - in my example above - this would return 'Parsnip' +-- public function getLastData():Object<a name="return_ajaxHelper.lastData.Cat0"> return ajaxHelper.lastData.Cat[0]; </a> +--</li>
</ul>
</div>
<div class="section"><h4>Other notes</h4>
<ul><li>If you want to pass context into the event simply add it to the URL</li>
<li>You don't have to use JSON you could use XML or roll your own protocol. I choose JSON as it is easy and fast</li>
</ul>
</div>
</div>
</div>

      </div>
    </div>
    <div class="clear">
      <hr/>
    </div>
    <div id="footer">
      <div class="xright">&#169;  
          2009
    
          ioko
          
  

  
    
            
  
    
  </div>
      <div class="clear">
        <hr/>
      </div>
    </div>
  </body>
</html>
